package com.lagou.filter;

import com.alibaba.fastjson.JSONObject;
import com.lagou.common.Response;
import com.lagou.service.CodeService;
import com.lagou.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * @ClassName TokenFilter
 * @Description 统一认证过滤器
 * @Author playboy
 * @Date 2021/6/26 12:55 下午
 * @Version 1.0
 **/
@Component
public class TokenFilter implements GlobalFilter, Ordered {
	private static Logger log = LoggerFactory.getLogger(TokenFilter.class);

	@Reference
	private UserService userService;
	@Reference
	private CodeService codeService;

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		ServerHttpRequest request = exchange.getRequest();
		ServerHttpResponse response = exchange.getResponse();
		String path = request.getPath().toString();
		if (path.startsWith("/api/user/login")) {
			String[] params = path.split("/");
			//登录
			String token = userService.login(params[4], params[5]);
			Response resp = Response.getSuccessResponse("登录成功", null);
			if (ObjectUtils.isEmpty(token)) {
				//登录失败
				resp = Response.getFailResponse("用户名或者密码错误", null);
			} else {
				ResponseCookie.ResponseCookieBuilder responseCookieBuilder = ResponseCookie.from("token", token);
				ResponseCookie responseCookie = responseCookieBuilder.path("/").build();
				response.addCookie(responseCookie);
			}
			DataBuffer wrap =
					response.bufferFactory().wrap(JSONObject.toJSONString(resp).getBytes(StandardCharsets.UTF_8));
			response.setStatusCode(HttpStatus.OK);
			response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
			return response.writeWith(Mono.just(wrap));
		} else if (path.startsWith("/api/user/register")) {
			//注册
			Response resp = Response.getFailResponse("注册失败", null);
			String[] params = path.split("/");
			//判断是否已经注册
			boolean registered = userService.isRegistered(params[4]);
			if (registered) {
				//已注册
				resp.setMsg("该邮箱已被注册");
			} else {
				Integer validate = codeService.validate(params[4], params[6]);
				if (validate.intValue() == 0) {
					//验证码没有问题
					boolean register = userService.register(params[4], params[5], params[6]);
					if (register) {
						resp.setFlag(true);
						resp.setMsg("注册成功");
						//注册成功后,调用登录接口获取token
						String token = userService.login(params[4], params[5]);
						ResponseCookie.ResponseCookieBuilder responseCookieBuilder = ResponseCookie.from("token", token);
						ResponseCookie responseCookie = responseCookieBuilder.path("/").build();
						response.addCookie(responseCookie);
					} else {
						resp.setMsg("注册失败");
					}
				} else if (validate.intValue() == 1) {
					resp.setMsg("验证码错误");
				} else if (validate.intValue() == 2) {
					resp.setMsg("验证码已超时，请重新获取");
				}
			}
			DataBuffer wrap =
					response.bufferFactory().wrap(JSONObject.toJSONString(resp).getBytes(StandardCharsets.UTF_8));
			response.setStatusCode(HttpStatus.OK);
			response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
			return response.writeWith(Mono.just(wrap));
		} else if (path.startsWith("/api/code/create/")) {
			return chain.filter(exchange);
		}
		HttpCookie token = request.getCookies().getFirst("token");
		//判断是否包含token
		if (ObjectUtils.isEmpty(token)) {
			Response resp = Response.getFailResponse("请先登录", null);
			DataBuffer wrap =
					response.bufferFactory().wrap(JSONObject.toJSONString(resp).getBytes(StandardCharsets.UTF_8));
			response.setStatusCode(HttpStatus.UNAUTHORIZED);
			response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
			return response.writeWith(Mono.just(wrap));
		} else {
			//判断token是否已经过期
			String info = userService.info(token.getValue());
			if (ObjectUtils.isEmpty(info)) {
				Response resp = Response.getFailResponse("token已过期，请重新登录", null);
				DataBuffer wrap =
						response.bufferFactory().wrap(JSONObject.toJSONString(resp).getBytes(StandardCharsets.UTF_8));
				response.setStatusCode(HttpStatus.UNAUTHORIZED);
				response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
				return response.writeWith(Mono.just(wrap));
			}
		}
		return chain.filter(exchange);
	}

	@Override
	public int getOrder() {
		return 1;
	}
}
